package com.dgut.smart_house.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.dgut.smart_house.shiro.CrosFilter;
import com.dgut.smart_house.shiro.LogInterceptor;
import com.dgut.smart_house.shiro.UserRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    //创建ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        //设置安全管理
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        Map<String, String> filterMap = new LinkedHashMap<String, String>();
        Map<String, Filter> filtersMap = new LinkedHashMap<>();
        //自定义过滤器
        filtersMap.put("authc",  logInterceptor());
        filtersMap.put("authc",  crosFilter());

        shiroFilterFactoryBean.setFilters(filtersMap);
        /*
        anon:无需认证可以访问;
        authc:必须认证才可以访问;
        user:如果使用rememberMe的功能可以直接访问;
        perms:该资源必须的得到资源权限才可以访问;
        role:该资源必须得到角色权限才可以访问;
        */

        filterMap.put("/data/api/**", "user");
        filterMap.put("/websocket", "anon");
        filterMap.put("/js/**", "anon");
        filterMap.put("/css/**", "anon");
        filterMap.put("/img/**", "anon");
        filterMap.put("/webjars/**", "anon");
        filterMap.put("/api/login", "anon");

        filterMap.put("/login", "anon");
        filterMap.put("/toLogin", "anon");
        filterMap.put("/api/register", "anon");
        //filterMap.put("/api/signOut", "logout");

        /*
            授权过滤器
        */

        //通过注解 @RequiresPermissions("user:xxx")
        filterMap.put("/index", "perms[user:ordinary]");
        filterMap.put("/admin/**", "perms[user:admin]");
        filterMap.put("/**", "authc");



        //修改调整登录页面
        shiroFilterFactoryBean.setLoginUrl("/api/nologin");

        //设置未授权提示页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/api/noAuth");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);




        return shiroFilterFactoryBean;
    }


    //创建DefaultWebSecurityManager
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("usernameRealm") UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }


    //创建UserRealm
    @Bean(name = "usernameRealm")
    public UserRealm getusernameRealm() {
        UserRealm userRealm = new UserRealm();
        userRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return userRealm;
    }

    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }

    //md5加密
    @Bean(name = "credentialsMatcher")
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        // 散列算法:这里使用MD5算法;
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        // 散列的次数，比如散列两次，相当于 md5(md5(""));
        hashedCredentialsMatcher.setHashIterations(2);
        // storedCredentialsHexEncoded默认是true，此时用的是密码加密用的是Hex编码；false时用Base64编码
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);

        return hashedCredentialsMatcher;
    }



    @Bean(name = "logInterceptor")
    public LogInterceptor logInterceptor(){
        LogInterceptor logInterceptor = new LogInterceptor();
        return logInterceptor;
    }

    @Bean(name = "crosFilter")
    public CrosFilter crosFilter(){
        CrosFilter crosFilter = new CrosFilter();
        return crosFilter;
    }


}